// AdminServiceImpl.java
package com.neusoft.SPNursingHome.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neusoft.SPNursingHome.dao.AdminDao;
import com.neusoft.SPNursingHome.dao.ClientDao;
import com.neusoft.SPNursingHome.po.Admin;
import com.neusoft.SPNursingHome.po.Client;
import com.neusoft.SPNursingHome.po.ResponseBean;
import com.neusoft.SPNursingHome.redisDao.RedisDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminDao adminDao;
    @Autowired
    private ClientDao clientDao;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public IPage<Admin> listAll(String name, String role, long page, long size) {
        Page<Admin> pager = new Page<>(page, size);
        QueryWrapper<Admin> qw = new QueryWrapper<>();

        if (StringUtils.isNotBlank(name)) {
            qw.like("ad_name", name.trim());
        }
        if (StringUtils.isNotBlank(role)) {
            qw.eq("role", role);
        }

        return adminDao.selectPage(pager, qw);
    }

    @Override
    public ResponseBean<Void> resetPasswordToPhoneSuffix(Integer id) {
        Admin admin = adminDao.selectById(id);
        if (admin == null) {
            return new ResponseBean<>(404, "管理员不存在");
        }
        String phone = admin.getPhone();
        if (phone == null || phone.length() < 6) {
            return new ResponseBean<>(400, "手机号格式不正确，无法重置");
        }
        String raw = phone.substring(phone.length() - 6);
        String hashed = passwordEncoder.encode(raw);
        admin.setAdPassword(hashed);
        adminDao.updateById(admin);
        return new ResponseBean<>();
    }

    @Override
    public IPage<Admin> listCareAd(String name, long page, long size) {
        // 构造分页对象
        Page<Admin> pager = new Page<>(page, size);

        // 构造查询条件
        QueryWrapper<Admin> qw = new QueryWrapper<>();
        if (StringUtils.isNotBlank(name)) {
            qw.like("ad_name", name.trim());
        }
        qw.eq("role", "健康管家");

        // 执行分页查询
        return adminDao.selectPage(pager, qw);
    }

    @Override
    public ResponseBean<Void> unassignClient(Integer clientId) {
        int rows = clientDao.unassignById(clientId);
        if (rows != 1) {
            return new ResponseBean<>(500, "移除失败");
        }
        return new ResponseBean<>();
    }

    @Override
    public ResponseBean<Admin> getById(Integer id) {
        Admin admin = adminDao.selectById(id);
        if (admin == null) {
            return new ResponseBean<>(404, "管理员未找到");
        }
        return new ResponseBean<>(admin);
    }

    @Override
    public ResponseBean<Void> create(Admin admin) {
        String raw = admin.getAdPassword();
        String hashed = passwordEncoder.encode(raw);
        // **自测 matches**
        boolean selfMatch = passwordEncoder.matches(raw, hashed);

        admin.setAdPassword(hashed);
        adminDao.insert(admin);
        return new ResponseBean<>();
    }


    @Override
    public ResponseBean<Void> update(Admin admin) {
        // 1. 如果调用 update 时传来了新的密码，就要先哈希
        //    注意：如果前端没修改密码，这里可能拿到空或原始的哈希串，
        //    需要根据业务决定是否总是覆盖。
        if (admin.getAdPassword() != null && !admin.getAdPassword().isBlank()) {
            String raw = admin.getAdPassword();
            String hashed = passwordEncoder.encode(raw);
            admin.setAdPassword(hashed);
        }

        // 2. 然后再更新数据库
        int rows = adminDao.updateById(admin);
        if (rows != 1) {
            return new ResponseBean<>(500, "更新失败");
        }
        return new ResponseBean<>();
    }

    @Override
    public ResponseBean<Void> delete(Integer id) {
        int rows = adminDao.deleteById(id);
        if (rows != 1) {
            return new ResponseBean<>(500, "删除失败");
        }
        return new ResponseBean<>();
    }

    @Autowired private RedisDao redisDao;
    private static final Map<String, String> ROLE_MAP = Map.of(
            "管理员",   "ADMIN",
            "健康管家", "CARE_WORKER"
    );
    @Override
    public ResponseBean<String> login(String account, String password) {
        // 1. 按账号查
        Admin admin = adminDao.findByAccount(account);
        if (admin == null) {
            System.out.println(">>>> No admin found for account: " + account);
            return new ResponseBean<>(401, "账号或密码错误");
        }

        // 2. 用 BCrypt 校验密码
        boolean matches = passwordEncoder.matches(password, admin.getAdPassword());

        if (!matches) {
            System.out.println(">>>> Password mismatch for account: " + account);
            return new ResponseBean<>(401, "账号或密码错误");
        }

        // 3. 生成 Token 存 Redis（示例 2 小时过期）
        String token = UUID.randomUUID().toString();
        String mappedRole = ROLE_MAP.getOrDefault(admin.getRole(), admin.getRole());

        Map<String,Object> session = Map.of(
                "adminId",   admin.getAdId(),
                "adminName", admin.getAdName(),
                "role",      mappedRole
        );
        String json;
        try {
            json = new ObjectMapper().writeValueAsString(session);
        } catch (JsonProcessingException e) {
            throw new IllegalStateException("无法序列化会话信息", e);
        }
        redisDao.set("token:" + token, json, 2, TimeUnit.HOURS);

        return new ResponseBean<>(token);
    }

    @Override
    public ResponseBean<Admin> loginWithOutRedis(String account, String password) {
        Admin admin = adminDao.findByAccount(account);
        if (admin == null) {
            System.out.println(">>>> No admin found for account: " + account);
            return new ResponseBean<>(401, "账号或密码错误");
        }

        // 2. 用 BCrypt 校验密码
        boolean matches = passwordEncoder.matches(password, admin.getAdPassword());

        if (!matches) {
            System.out.println(">>>> Password mismatch for account: " + account);
            return new ResponseBean<>(401, "账号或密码错误");
        }
        return new ResponseBean<>(admin);
    }
    @Override
    public ResponseBean<IPage<Client>> listClientsByAdmin(Integer adminId, long page, long size) {
        // 1. 分页对象
        Page<Client> pager = new Page<>(page, size);

        // 2. 构造查询条件
        QueryWrapper<Client> qw = new QueryWrapper<>();
        qw.eq("care_admin_id", adminId);

        // 3. 调用 BaseMapper 提供的 selectPage
        IPage<Client> result = clientDao.selectPage(pager, qw);

        return new ResponseBean<>(result);
    }
}
